// ===================================
// <copyright>
// This file is part of LABSMFController.
//
//    LABSMFController is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    LABSMFController is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with LABSMFController.  If not, see <http://www.gnu.org/licenses/>.
//    Copyright 2011 David Bakker
//
//</copyright>
// <author>David Bakker</author>
// <email>mailto:DavidFBakker@gmail.com</email>
// <created>Saturday, May 07, 2011</created>
// <lastedit>Saturday, May 07, 2011</lastedit>
// ===================================

using System;
using System.Threading;
using GHIElectronics.NETMF.FEZ;
using LABSMFController.LABS;
using LABSMFController.LABS.Classses;
using LABSMFController.LABS.Devices;
using LABSMFController.LABS.Services;
using Microsoft.SPOT.Hardware;

namespace LABSMFController.LABS.Devices
{

    #region Nested type: HeaterDevice

    public class HeaterDevice
    {
        internal readonly OutputPort _outputPort1;
        internal readonly OutputPort _outputPort2;
        internal readonly OutputPort _outputPortLED;
        private bool _isOn;


        internal HeaterDevice()
        {
        }

        public HeaterDevice(int locationID, string description, FEZ_Pin.Digital pin1, FEZ_Pin.Digital pin2,
                            FEZ_Pin.Digital led)
        {
            Description = description;

            LocationID = locationID;
            BubblerLocationID = locationID;
            TempProbeLocationID = locationID;

            PIN1 = pin1;
            PIN2 = pin2;
            LED = led;
            HoldTemperature = -1;
            PIN1String = pin1.ToString();
            PIN2String = pin2.ToString();

            _outputPort1 = new OutputPort((Cpu.Pin) PIN1, false);
            _outputPort2 = new OutputPort((Cpu.Pin) PIN2, false);
            _outputPortLED = new OutputPort((Cpu.Pin) LED, false);

            Header = "Description,LocationID,PIN1String,PIN2String,IsOn,MAXHeaters,HoldTemperature";
        }

        public string Header { get; set; }
        public int LocationID { get; set; }
        public int BubblerLocationID { get; set; }
        public int TempProbeLocationID { get; set; }
        public int HoldTemperature { get; set; }
        public bool Run { get; set; }
        public string Description { get; private set; }
        private FEZ_Pin.Digital PIN1 { get; set; }
        private FEZ_Pin.Digital PIN2 { get; set; }
        private FEZ_Pin.Digital LED { get; set; }
        public string PIN1String { get; private set; }
        public string PIN2String { get; private set; }

        public bool IsOn
        {
            get { return _isOn; }
            private set
            {
                _isOn = value;
                _outputPortLED.Write(value);
            }
        }

        public string GetClientOutPut()
        {
            string ret = Description + "," + LocationID + "," + PIN1String + "," + PIN2String + "," + IsOn + "," +
                         HeaterServiceClass.MAXHeaters + "," + HoldTemperature + ";";
            return ret;
        }

        public void TurnOn()
        {
            var op = new OperateHeaterThread(this, true);
            IsOn = true;
        }

        public void TurnOff()
        {
            var op = new OperateHeaterThread(this, false);
            IsOn = false;
        }
    }

    #endregion
}

internal class OperateHeaterThread
{
    public HeaterDevice HeaterDevice;
    private DateTime StartTS;
    public bool TurnOn;

    public OperateHeaterThread(HeaterDevice heaterDevice, bool turnOn)
    {
        if (!heaterDevice.IsOn.Equals(turnOn))
            BeerProgram.Log(heaterDevice.Description + " turning " + turnOn, LoggingSeverity.Debug);

        HeaterDevice = heaterDevice;

        TurnOn = turnOn;
        StartTS = DateTime.Now;
        var thrd = new Thread(DoRun);
        thrd.Start();
    }

    private void DoRun()
    {
        int delay = Convert.ToInt32(Settings.GetSetting("HeaterRelayDelay"));
        if (HeaterDevice._outputPort1.Read() != TurnOn)
            HeaterDevice._outputPort1.Write(TurnOn);

        if (TurnOn)
            Thread.Sleep(delay);

        if (HeaterDevice._outputPort2.Read() != TurnOn)
            HeaterDevice._outputPort2.Write(TurnOn);
    }
}